﻿namespace Vibstudio.NetConfigurator.UI.ViewModels
{
    #region Namespaces

    using System;
    using System.ComponentModel;
    using System.Diagnostics;

    using Vibstudio.NetConfigurator.Globalization;

    #endregion

    public abstract class ViewModelBase : INotifyPropertyChanged, IDisposable
    {
        #region Fields

        private string _isBackupLabel;

        private string _applicationFilesToolTip;

        private string _configurationFilesToolTip;

        private string _chooseApplicationPathToolTip;

        private string _runConfigurationToolTip;

        private string _runAutoCompositionToolTip;

        private string _goToHomeToolTip;

        private string _validateUrlToolTip;

        private string _applicationColumnName;

        private string _configurationColumnName;

        private string _outcomeColumnName;

        private string _messageColumnName;

        private string _urlColumnName;

        #endregion

        #region Properties

        public virtual string DisplayName { get; set; }

        public virtual string IsBackupLabel
        {
            get { return _isBackupLabel; }
            set
            {
                _isBackupLabel = value;
                OnPropertyChanged("IsBackupLabel");
            }
        }

        public virtual string ApplicationFilesToolTip
        {
            get { return _applicationFilesToolTip; }
            set
            {
                _applicationFilesToolTip = value;
                OnPropertyChanged("ApplicationFilesToolTip");
            }
        }

        public virtual string ConfigurationFilesToolTip
        {
            get { return _configurationFilesToolTip; }
            set
            {
                _configurationFilesToolTip = value;
                OnPropertyChanged("ConfigurationFilesToolTip");
            }
        }

        public virtual string ChooseApplicationPathToolTip
        {
            get { return _chooseApplicationPathToolTip; }
            set
            {
                _chooseApplicationPathToolTip = value;
                OnPropertyChanged("ChooseApplicationPathToolTip");
            }
        }

        public virtual string RunConfigurationToolTip
        {
            get { return _runConfigurationToolTip; }
            set
            {
                _runConfigurationToolTip = value;
                OnPropertyChanged("RunConfigurationToolTip");
            }
        }

        public virtual string RunAutoCompositionToolTip
        {
            get { return _runAutoCompositionToolTip; }
            set
            {
                _runAutoCompositionToolTip = value;
                OnPropertyChanged("RunAutoCompositionToolTip");
            }
        }

        public virtual string GoToHomeToolTip
        {
            get { return _goToHomeToolTip; }
            set
            {
                _goToHomeToolTip = value;
                OnPropertyChanged("GoToHomeToolTip");
            }
        }

        public virtual string ValidateUrlToolTip
        {
            get { return _validateUrlToolTip; }
            set
            {
                _validateUrlToolTip = value;
                OnPropertyChanged("ValidateUrlToolTip");
            }
        }

        public virtual string ApplicationColumnName
        {
            get { return _applicationColumnName; }
            set
            {
                _applicationColumnName = value;
                OnPropertyChanged("ApplicationColumnName");
            }
        }

        public virtual string ConfigurationColumnName
        {
            get { return _configurationColumnName; }
            set
            {
                _configurationColumnName = value;
                OnPropertyChanged("ConfigurationColumnName");
            }
        }

        public virtual string ConfigurationFileColumnName
        {
            get { return _configurationColumnName; }
            set
            {
                _configurationColumnName = value;
                OnPropertyChanged("ConfigurationFileColumnName");
            }
        }

        public virtual string OutcomeColumnName
        {
            get { return _outcomeColumnName; }
            set
            {
                _outcomeColumnName = value;
                OnPropertyChanged("OutcomeColumnName");
            }
        }

        public virtual string MessageColumnName
        {
            get { return _messageColumnName; }
            set
            {
                _messageColumnName = value;
                OnPropertyChanged("MessageColumnName");
            }
        }

        public virtual string UrlColumnName
        {
            get { return _urlColumnName; }
            set
            {
                _urlColumnName = value;
                OnPropertyChanged("UrlColumnName");
            }
        }

        #endregion

        #region Ctor(s)

        protected ViewModelBase()
        {
            SetLabels();
        }

        protected ViewModelBase(bool throwOnInvalidPropertyName)
        {
            ThrowOnInvalidPropertyName = throwOnInvalidPropertyName;
        }

        #endregion

        #region Debugging Aides

        [Conditional("DEBUG")]
        [DebuggerStepThrough]
        public void VerifyPropertyName(string propertyName)
        {
            if (TypeDescriptor.GetProperties(this)[propertyName] == null)
            {
                string msg = string.Format("Invalid property name: {0}", propertyName);

                if (ThrowOnInvalidPropertyName)
                {
                    throw new Exception(msg);
                }

                Debug.Fail(msg);
            }
        }

        /// <summary>
        /// Returns whether an exception is thrown, or if a Debug.Fail() is used
        /// when an invalid property name is passed to the VerifyPropertyName method.
        /// The default value is false, but subclasses used by unit tests might 
        /// override this property's getter to return true.
        /// </summary>
        protected virtual bool ThrowOnInvalidPropertyName { get; private set; }

        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            VerifyPropertyName(propertyName);

            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                var e = new PropertyChangedEventArgs(propertyName);
                handler(this, e);
            }
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            OnDispose();
        }

        protected virtual void OnDispose()
        {
        }

#if DEBUG
        ~ViewModelBase()
        {
            string msg = string.Format("{0} ({1}) ({2}) Finalized", GetType().Name, DisplayName, GetHashCode());
            Debug.WriteLine(msg);
        }
#endif

        #endregion

        #region Protected methods

        protected void SetLabels()
        {
            IsBackupLabel = Labeler.Get.BackupFiles.ToString();
            ApplicationFilesToolTip = Labeler.Get.ApplicationsFile.ToString();
            ConfigurationFilesToolTip = Labeler.Get.ConfigurationsFile.ToString();
            ChooseApplicationPathToolTip = Labeler.Get.ChooseApplicationsPathToConfigure.ToString();
            RunConfigurationToolTip = Labeler.Get.RunConfiguration.ToString();
            GoToHomeToolTip = Labeler.Get.GoToHome.ToString();
            ValidateUrlToolTip = Labeler.Get.ValidateUrl.ToString();
            ApplicationColumnName = Labeler.Get.Application.ToString();
            ConfigurationColumnName = Labeler.Get.Configuration.ToString();
            ConfigurationFileColumnName = Labeler.Get.ConfigurationFile.ToString();
            OutcomeColumnName = Labeler.Get.Outcome.ToString();
            MessageColumnName = Labeler.Get.Message.ToString();
            UrlColumnName = Labeler.Get.Url.ToString();
            RunAutoCompositionToolTip = Labeler.Get.RunAutoComposition.ToString();
        }

        #endregion
    }
}